package cn.buk.qms.service;

import cn.buk.api.airskyhk.dto.FlightInfo;
import cn.buk.api.airskyhk.dto.*;
import cn.buk.api.wechat.dto.WxTemplateDataParam;
import cn.buk.api.wechat.dto.WxTemplateSend;
import cn.buk.common.JsonResult;
import cn.buk.common.dto.CommonDto;
import cn.buk.common.flight.dto.FlightBasicInfo;
import cn.buk.common.util.FlightTicketUtil;
import cn.buk.qms.SmsUtil;
import cn.buk.tms.dao.DetrDao;
import cn.buk.tms.dao.FlightChangeOrderDao;
import cn.buk.tms.dao.FlightOrderDao;
import cn.buk.tms.dto.CustomerServiceTemplateDto;
import cn.buk.tms.dto.FlightChangeOrderDetailDto;
import cn.buk.tms.dto.FlightChangeOrderDto;
import cn.buk.tms.dto.FlightRefundTicket;
import cn.buk.tms.entity.config.EnterpriseConfig;
import cn.buk.tms.entity.order.OrderAttachment;
import cn.buk.tms.entity.order.OrderNoInfo;
import cn.buk.tms.sc.SearchFlightOrderCriteria;
import cn.buk.tms.common.dto.flight.BaseChangeOrderFlightDto;
import cn.buk.tms.entity.bill.BillInfo;
import cn.buk.tms.entity.misc.*;
import cn.buk.tms.entity.order.flight.FlightChangeOrder;
import cn.buk.tms.entity.order.flight.FlightChangeOrderDetail;
import cn.buk.tms.entity.order.flight.FlightOrder;
import cn.buk.tms.flight.service.EtermService;
import cn.buk.tms.flight.util.FlightOrderUtil;
import cn.buk.tms.flight.dto.response.ChangeOrderResponseDto;
import cn.buk.common.util.CheckUtil;
import cn.buk.common.util.DateUtil;
import cn.buk.common.util.VerifyCodeUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static cn.buk.common.Constant.*;
import static cn.buk.tms.entity.config.EnterpriseConfig.*;
import static cn.buk.tms.entity.order.flight.FlightChangeOrder.ORDER_STATUS_CANCELED;
import static cn.buk.tms.entity.order.flight.FlightChangeOrder.ORDER_STATUS_FINISHED;
import static cn.buk.qms.service.BaseFlightOrderService.CZ_NDC_AMOUNT_BALANCE;
import static cn.buk.tms.common.constant.TmsConstant.FLIGHT_AUTO_TICKETING_NDC_CZ;
import static cn.buk.tms.common.constant.TmsOrderConstant.ORDER_TYPE_FLIGHT_CHANGE;
import static java.nio.charset.StandardCharsets.UTF_8;

/**
 * @author yfdai
 */
@Service
public class FlightChangeOrderServiceImpl extends BaseOrderService implements
    FlightChangeOrderService {

  private static final Logger logger = LogManager.getLogger(FlightChangeOrderServiceImpl.class);

  private static final String CHANGE_SMS_TEMPLATE_1 = "%s乘机人：%s，改签后行程：%s，票号：%s。";

  @Autowired
  private FlightChangeOrderDao dao;

  @Autowired
  private FlightOrderDao flightOrderDao;

  @Autowired
  private DetrDao detrDao;

  @Autowired
  private EtermService etermService;

  @Override
  @Secured({"ROLE_OPERATOR", "ROLE_SUPERVISOR", "ROLE_ADMIN"})
  public JsonResult createFlightChangeOrder(final int enterpriseId, String username,
      FlightChangeOrderDto dto) {
    final String ticketNo = dto.getTicketNo();
    final int ticketLength = StringUtils.trimToEmpty(ticketNo).length();
    if (ticketLength != 13 && ticketLength != 14) {
      return JsonResult.createJsonResult(-1, "票号错误");
    }

    final String balCode = ticketNo.substring(0, 3);
    final String tickNo = ticketLength == 14 ? ticketNo.substring(4) : ticketNo.substring(3);

    // 检查该票号是否已有改签订单
    var jr = isTicketChanged(enterpriseId, balCode, tickNo, dto.getChangeCount());
    if (jr != null) {
      return jr;
    }

    //校验新航班的起飞日期
    int oldFlightCount = 0;
    int newFlightCount = 0;
    for (var detailDto : dto.getFlights()) {
      jr = validateFlightChangeInfo(detailDto);
      if (jr != null) {
        return jr;
      }

      if (detailDto.getFltType() == 0) {
        oldFlightCount++;
      } else if (detailDto.getFltType() == 1) {
        newFlightCount++;
      }
    }

    if (oldFlightCount == 0 || newFlightCount == 0) {
      return JsonResult.createJsonResult(-4, "航班信息数据有误：" + oldFlightCount + ", " + newFlightCount);
    }

    int retCode = doCreateChangeOrder(enterpriseId, username, balCode, tickNo, dto.getName(), dto.getIdNo(), dto);
    var jsonResult = JsonResult.createJsonResult(retCode);
    if (retCode > 0) {
      jsonResult.setReturnCode(retCode);
    } else if (retCode == -100) {
      jsonResult.setErrmsg("保存时出现错误，请检查是否已有改签单。");
    }

    return jsonResult;
  }

  private JsonResult validateFlightChangeInfo(FlightChangeOrderDetailDto detailDto) {
    if (StringUtils.isBlank( detailDto.getFlightNo())
            || StringUtils.isBlank( detailDto.getSubclass())) {
      return JsonResult.createJsonResult(-1, "航班数据有错");
    }

    if (!FlightOrderUtil.isValidAirportCode(detailDto.getDport())) {
      return JsonResult.createJsonResult(-5, "出发(" + detailDto.getDport() + ")" + "不符合格式要求");
    }
    if (!FlightOrderUtil.isValidAirportCode(detailDto.getAport())) {
      return JsonResult.createJsonResult(-5, "到达(" + detailDto.getAport() + ")" + "不符合格式要求");
    }

    if (!CheckUtil.isDate(detailDto.getDdate())) {
      return JsonResult.createJsonResult(-5, "出发日期(" + detailDto.getDdate() + ")" + "不符合格式要求");
    }

    try {
      Date newDdate = DateUtil.convertToDate(detailDto.getDdate(), DATE_YYYY_MM_DD);
      if (detailDto.getFltType() == 1 && DateUtil.getCurDate().getTime() > newDdate.getTime()) {
        return JsonResult.createJsonResult(-3, detailDto.getDdate() + "-起飞日期不能早于今天");
      }
    } catch (ParseException e) {
      logger.error("{}: {}", detailDto.getDdate(), e.getMessage());
      return JsonResult.createJsonResult(-100, "航班信息有错误");
    }
    return null;
  }

  private JsonResult isTicketChanged(final int enterpriseId, final String balCode, final String tickNo, final int changeCount) {
    SearchFlightOrderCriteria sc = new SearchFlightOrderCriteria();
    sc.setBalCode(balCode);
    sc.setTicketNo(tickNo);
    List<FlightChangeOrder> orders = dao.searchFlightChangeOrder(enterpriseId, sc, null);
    for (FlightChangeOrder order : orders) {
      if (order.getChangeCount() >= changeCount) {
        return JsonResult.createJsonResult(-2, balCode + tickNo + "-该票号已经创建了改签单(" + order.getChangeCount() + ")");
      }
    }

    return null;
  }

  @Override
  public JsonResult createFlightChangeOrderV2(int enterpriseId, String username, FlightChangeOrderDto dto) {
    if (dto.getTickets().isEmpty()) {
      return JsonResult.createJsonResult(-1, "请选择需要改签的票号");
    }

    int selectCount = 0;
    for (var t : dto.getTickets()) {
      if (!t.isSelected()) {
        continue;
      }

      selectCount++;

      var jr = validateTicketChangeInfo(enterpriseId, t, dto);
      if (jr != null) {
        return jr;
      }
    }

    if (selectCount < 1) {
      return JsonResult.createJsonResult(-2, "请选择需要改签的票号");
    }

    int created = 0;
    int retCode = 0;
    for (var t : dto.getTickets()) {
      if (!t.isSelected()) {
        continue;
      }

      final String ticketNo0 = t.getTicketNo();
      final String balCode = ticketNo0.substring(0, 3);
      final String tickNo = getTenTicketNo(ticketNo0);

      retCode = doCreateChangeOrder(enterpriseId, username, balCode, tickNo, t.getName(), t.getIdNo(), dto);
      if (retCode > 0) {
        created++;
      }
    }

    JsonResult jsonResult = JsonResult.createJsonResult(created);
    if (retCode > 0) {
      jsonResult.setReturnCode(retCode);
    } else if (retCode == -100) {
      jsonResult.setErrmsg("保存时出现错误，请检查是否已有改签单。");
    }

    return jsonResult;
  }

  private String getTenTicketNo(final String ticketNo) {
    return ticketNo.length() == 14 ? ticketNo.substring(4) : ticketNo.substring(3);
  }

  private JsonResult validateTicketChangeInfo(final int enterpriseId, FlightRefundTicket t, FlightChangeOrderDto dto) {

    if (!FlightTicketUtil.verifyTicketNo(t.getTicketNo())) {
      return JsonResult.createJsonResult(-1, "票号格式不符合要求");
    }

    final String ticketNo0 = t.getTicketNo();
    final String balCode = ticketNo0.substring(0, 3);
    final String tickNo = ticketNo0.length() == 14 ? ticketNo0.substring(4) : ticketNo0.substring(3);

    // 检查该票号是否已经改签订单
    var jr = isTicketChanged(enterpriseId, balCode, tickNo, dto.getChangeCount());
    if (jr != null) {
      return jr;
    }

    //校验新航班的起飞日期
    int oldFlightCount = 0;
    int newFlightCount = 0;
    for (var detailDto : dto.getFlights()) {
      if (detailDto.getFltType() == 0) {
        oldFlightCount++;
      } else if (detailDto.getFltType() == 1) {
        newFlightCount++;
      }
      //需要校验改签后的航班的数据是否准确：三字代码，航班号，日期格式，时间格式
      jr = validateFlightChangeInfo(detailDto);
      if (jr != null) {
        return jr;
      }

    }

    if (oldFlightCount == 0 || newFlightCount == 0) {
      return JsonResult.createJsonResult(-4, "航班信息数据有误：" + oldFlightCount + ", " + newFlightCount);
    }

    return null;
  }

  private int doCreateChangeOrder(int enterpriseId, String username, String balCode, String tickNo,
      String name, String idNo, FlightChangeOrderDto dto) {
    FlightChangeOrder info = new FlightChangeOrder();

    info.setEnterpriseId(enterpriseId);
    info.setBalanceCode(balCode);
    info.setTicketNo(tickNo);
    info.setChangeCount(dto.getChangeCount());

    info.setOldPnrNo(dto.getOldPnrNo());

    info.setPsgName(name);
    info.setIdNo(idNo);

    info.setParvalue(dto.getParvalue());
    info.setTax(dto.getTax());
    info.setAirChangeCharge(dto.getAirChangeFee());
    info.setServiceCharge(dto.getServiceCharge());

    info.setRemark(dto.getRemark());
    info.setOperator(username);

    info.setChangeType(dto.getReasonCode());

    info.setOrderId(dto.getOrderId());
    info.setOrderNo(dto.getOrderNo());
    info.setParentChangeOrderNo(dto.getParentChangeOrderNo());

    info.setIntlTicket(dto.getIntlTicket());

    info.setChangeOrderNo(
        orderNoGenerator.generateOrderNo(enterpriseId, OrderNoInfo.ORDER_FLIGHT_CHANGE));

    FlightOrder flightOrder = flightOrderDao.getOrderDetailById(dto.getOrderId());
    if (flightOrder != null) {

      var t1 = info;
      var t0 = flightOrder;

      t1.setCustomerType(t0.getCustomerType());
      t1.setCustomer(t0.getCustomer());

      t1.setCostCenter(t0.getCostCenter());
      t1.setProjectName(t0.getProjectName());

      t1.setSupplier(t0.getSupplier());
      t1.setPaymentMethod(t0.getPaymentMethod());

      t1.setPayType(t0.getPayType());
      t1.setPayRemark(t0.getPayRemark());
    }

    for (FlightChangeOrderDetailDto detailDto : dto.getFlights()) {
      FlightChangeOrderDetail detail = new FlightChangeOrderDetail();
      detail.setOrder(info);
      detail.setEnterpriseId(enterpriseId);

      detail.getFlight().setDepartureAirport(detailDto.getDport());
      detail.getFlight().setDepartureAirportName(detailDto.getDportName());
      detail.getFlight().setDepartureTerminal(detailDto.getDterm());

      detail.getFlight().setArrivalAirport(detailDto.getAport());
      detail.getFlight().setArrivalAirportName(detailDto.getAportName());
      detail.getFlight().setArrivalTerminal(detailDto.getAterm());

      detail.getFlight().setDepartureDate(detailDto.getDdate());
      detail.getFlight().setDepartureTime(detailDto.getDtime());
      detail.getFlight().setArrivalTime(detailDto.getAtime());

      detail.getFlight().setSubclass(detailDto.getSubclass());
      detail.getFlight().setFlightNo(detailDto.getFlightNo());

      detail.setFlightType(detailDto.getFltType());

      info.getFlights().add(detail);
    }

    int retCode = dao.createFlightChangeOrder(info);
    if (retCode > 0) {
      //发送给群聊会话
      try {
        final String content = "有新的改签单了(" + info.getChangeOrderNo() + ", " + info.getSupplier().getName() + ")";
        sendChangeOrderAlertToWwAppChat(enterpriseId, content);
      } catch (Exception ex) {
        logger.error(ex.getMessage());
      }
    }

    return retCode;
  }


  @Override
  public List<ChangeOrderResponseDto> searchFlightChangeOrder(int enterpriseId, final int userId,
                                                              SearchFlightOrderCriteria sc) {
    List<Integer> allowedCustomerIds = searchAllowedCustomerIds(enterpriseId, userId);

    if (isOnlySeeOwn(enterpriseId, userId)) {
      //仅能查看自己的订单
      User user = userDao.getUserById(userId);
      sc.setOp1(user.getUsername());
    }

    List<FlightChangeOrder> list = dao.searchFlightChangeOrder(enterpriseId, sc, allowedCustomerIds);

    for (FlightChangeOrder info : list) {
      FlightOrderUtil.cleanFlightChangeOrder(info);
    }

    final boolean needHideCustomerName = isNeedHideCustomerName(enterpriseId, userId);
    User user = userDao.getUserById(userId);
    for (FlightChangeOrder order : list) {
      maskCustomerName(order.getCustomer(), order.getOperator(), user.getUsername(), needHideCustomerName);
    }

    List<ChangeOrderResponseDto> dtos = new ArrayList<>();
    for(FlightChangeOrder o: list) {
      dtos.add(ChangeOrderResponseDto.createdBy(o));
    }

    //处理机场的中文名
    for(ChangeOrderResponseDto dto: dtos) {
      for(BaseChangeOrderFlightDto fltDto: dto.getFlights()) {
        processAirportName(fltDto);
      }
    }

    return dtos;
  }

  @Override
  public CommonDto<ChangeOrderResponseDto> searchFlightChangeOrder2(int enterpriseId, int userId, SearchFlightOrderCriteria sc) {
    var tickets = this.searchFlightChangeOrder(enterpriseId, userId, sc);

    CommonDto<ChangeOrderResponseDto> commonDto = new CommonDto<>();
    commonDto.setDataList(tickets);
    commonDto.setPage(sc.getPage());

    return commonDto;
  }

  @Override
  public ChangeOrderResponseDto getFlightChangeOrderDetail(final int enterpriseId, final int userId, final int id) {
    FlightChangeOrder o = dao.getFlightChangeOrderDetail(id);

    if (o == null || o.getEnterpriseId() != enterpriseId) {
      return null;
    }

    final int customerId = o.getCustomer() == null ? 0 : o.getCustomer().getId();

    //查看当前用户是否允许查看该客户的订单
    if (!isCustomerAllowed(enterpriseId, userId, customerId)) {
      return null;
    }

    //是否要对当前用户隐藏客户名称
    if (isNeedHideCustomerName(enterpriseId, userId)) {
      User user = userDao.getUserById(userId);
      maskCustomerName(o.getCustomer(), o.getOperator(), user.getUsername(), true);
    }

    ChangeOrderResponseDto dto = ChangeOrderResponseDto.createdBy(o);
    //处理机场的中文名
    for (BaseChangeOrderFlightDto fltDto : dto.getFlights()) {
      processAirportName(fltDto);
    }

    //获取DETR的信息
    final String ticketNo = o.getNewTicketNo().length() >= 13 ?
            o.getNewTicketNo() :
            o.getBalanceCode() + "-" + o.getTicketNo();

    //从DETR中获取对应的航段信息
    DetrInfo detrInfo = detrDao.getByTicketNo(enterpriseId, ticketNo.replace("-", ""));
    if (detrInfo != null) {
      for (DetrInfoFlight detrInfoFlight : detrInfo.getFlights()) {
        FlightBasicInfo info = new FlightBasicInfo();
        BeanUtils.copyProperties(detrInfoFlight, info);

        info.setSubclass(detrInfoFlight.getSubClass());
        try {
          if (detrInfoFlight.getDdate() != null && detrInfoFlight.getDdate().length() == 10) {
            info.setDdate(DateUtil.convertToDate(detrInfoFlight.getDdate(), DATE_YYYY_MM_DD));
          }
        } catch (Exception ex) {
          ex.printStackTrace();
        }

        processAirportName(info);

        dto.getDetrFlights().add(info);
      }
    }

    //取得相关的 短信
    List<SmsDetail> smsDetails = smsDao.searchSmsByOrderNo(enterpriseId, o.getChangeOrderNo());
    processSmsDetails(smsDetails, dto.getSmsDetails());

    //获取相关的附件
    List<OrderAttachment> attachments = dao.searchAttachments(enterpriseId, o.getId());
    processAttachments(enterpriseId, attachments, dto.getAttachments());

    return dto;
  }



  private void processAirportName(FlightBasicInfo fltDto) {
    if (fltDto.getDportName() == null) {
      fltDto.setDportName(getAirportName(fltDto.getDport()));
    }
    if (fltDto.getAportName() == null) {
      fltDto.setAportName(getAirportName(fltDto.getAport()));
    }
  }

  @Override
  public List<OperationLog> searchFlightChangeOrderHistory(int enterpriseId, int id) {
    return dao.searchFlightChangeOrderHistory(enterpriseId, id);
  }

  @Override
  public JsonResult processFlightChangeOrder(final int enterpriseId, final String username, final int orderId) {
    //DONE 判断授信额度是否足够
    var orderInfo = dao.getFlightChangeOrderDetail(orderId);
    if (orderInfo == null || orderInfo.getEnterpriseId() != enterpriseId) {
      return JsonResult.createJsonResult(-404, "改签单不存在");
    }

    if (orderInfo.getCustomer() != null && orderInfo.getCustomer().getCustomerEnterpriseId() >0) {
      //该客户可以判断授信额度
      final int customerEnterpriseId = orderInfo.getCustomer().getCustomerEnterpriseId();
      final double totalAmount = orderInfo.getAirChangeCharge() + orderInfo.getServiceCharge();
      if (isOverCreditLimit(enterpriseId, customerEnterpriseId, totalAmount)) {
        return JsonResult.createJsonResult(-100, "订单金额(" + totalAmount + ")大于可用额度");
      }
    }

    //前台系统提交的订单供应商处为空，联系人电话也可能为空
    //TODO 将检查改签单的供应商和乘机人的联系电话放到此处 yfdai 2021-10-17

    return JsonResult
        .createJsonResult(dao.processFlightChangeOrder(enterpriseId, username, orderId));
  }

  @Override
  public JsonResult cancelFlightChangeOrder(int enterpriseId, String username, int orderId,
      String remark) {
    return JsonResult
        .createJsonResult(dao.cancelFlightChangeOrder(enterpriseId, username, orderId, remark));
  }

  @Override
  @Secured({RoleInfo.ROLE_ADMIN})
  public JsonResult reopenFlightChangeOrder(int enterpriseId, String username, int orderId) {
    return JsonResult
        .createJsonResult(dao.reopenFlightChangeOrder(enterpriseId, username, orderId));
  }

  @Override
  public JsonResult finishFlightChangeOrder(final int enterpriseId, final String username, final int orderId,
       String pnrNo,  String ticketNo) {

    var order = dao.getFlightChangeOrderDetail(orderId);
    if (order == null || order.getEnterpriseId() != enterpriseId) {
      return JsonResult.createJsonResult(-2, "改签单不存在");
    }

    if (!username.equalsIgnoreCase(order.getTicketer())) {
      doSendAlert(enterpriseId, username + "替" + order.getTicketer() + "完成了改签单" + order.getChangeOrderNo() + ".",
              null, EntDepartment.DEPT_TICKETING);
    }

    if (StringUtils.isNotBlank(ticketNo) && !FlightTicketUtil.verifyTicketNo(ticketNo.trim())) {
      //回填了票号，则校验格式
        return JsonResult.createJsonResult(-1, ticketNo + ": 不符合格式要求");
    }

    if (StringUtils.isNotBlank(pnrNo)) {
      pnrNo = pnrNo.trim().toUpperCase();
      if (pnrNo.length() < 5 || pnrNo.length() > 6) {
        return JsonResult.createJsonResult(-1, pnrNo + ": 不符合格式要求");
      }
    }

    //校验服务费是否符合服务费模板设置
    JsonResult v = validateChangeOrderServiceCharge(enterpriseId, order);
    if (v != null) {
      return v;
    }


    int retCode = dao.finishFlightChangeOrder(enterpriseId, username, orderId, pnrNo, processTicketNo(ticketNo));

    //改签完成，自动发送短信, 需要和机票订单一样，判断该客户是否自动发送信息
    if (retCode == ORDER_STATUS_FINISHED && order.getCustomer() != null && order.getCustomer().getSmsMode() == 1) {
      dao.appendFlightChangeOrderLog(enterpriseId, orderId, username, "^_^将自动发送短信");
      sendFlightChangeOrderSms(enterpriseId, username, orderId, null, 0, null);
    } else {
      dao.appendFlightChangeOrderLog(enterpriseId, orderId, username, "系统设定不需要自动发送短信");
    }

    if (retCode == ORDER_STATUS_FINISHED) {
      importService.importFlightChangeOrder(enterpriseId, username, orderId);
    }

    //TODO 发送微信模板消息通知微信用户
    try {
      doSendWeixinTemplateMessage("oEK0T0sye8VHx3ywNellAehPY-8Y", enterpriseId, order);
    } catch (Exception ex) {
      ex.printStackTrace();
    }

    return JsonResult.createJsonResult(retCode);
  }

  private String processTicketNo(String ticketNo) {
    ticketNo = ticketNo.trim();
    if (ticketNo.length() == 13) {
      ticketNo = ticketNo.substring(0, 3) + "-" + ticketNo.substring(3);
    }
    return ticketNo;
  }

  private void doSendWeixinTemplateMessage(final String openid, final int enterpriseId, final FlightChangeOrder changeOrder) {
    WxTemplateSend wxTplRq = new WxTemplateSend();
    wxTplRq.setTouser(openid);
    wxTplRq.setTemplate_id("8pyYUR-EOptbv5sMIE2X8r17g33EkWBJGlOPWs56Nnw");

    String firstData = "您好，您的机票已成功改签。请持有效证件提早到机场办理乘机手续。";
    wxTplRq.getData().setFirst(WxTemplateDataParam.createByValue(firstData));

    wxTplRq.getData().setOrderId(WxTemplateDataParam.createByValue(changeOrder.getOrderNo()));

    var psgNames = changeOrder.getPsgName();
    wxTplRq.getData().setPersonName(WxTemplateDataParam.createByValue(psgNames));

    processOrderAirportName(changeOrder);
    final String smsRouteInfo = SmsUtil.convertChangeOrder(changeOrder);
    wxTplRq.getData().setFlightInfo(WxTemplateDataParam.createByValue(smsRouteInfo));


    FlightOrder orderInfo = flightOrderDao.getOrderDetailByOrderNo(enterpriseId, changeOrder.getOrderNo());

    final String authCode = VerifyCodeUtil.MD5(openid + "_" + enterpriseId + "_" + orderInfo.getId() + "_" + DateUtil.getCurDateTime().getTime());
    int retCode = enterpriseDao.createAuthCodeInfo(authCode, null, enterpriseId, OrderNoInfo.ORDER_FLIGHT,
            orderInfo.getId(), null);
    if (retCode == 0) {
      return;
    }

    final String url = tmsWxsUrl + "/h5/flt/order/" + orderInfo.getId() + "?auth_code=" + authCode;
    wxTplRq.setUrl(url);

    doSendWeixinTemplateMessage(enterpriseId, wxTplRq);
  }



  /**
   * 校验改签单的服务费
   */
  private JsonResult validateChangeOrderServiceCharge(final int enterpriseId, FlightChangeOrder o) {
    if (o.getCustomer() == null || o.getCustomer().getTemplateCode() == null) {
      return null;
    }

    final String tplCode = o.getCustomer().getTemplateCode();
    CustomerServiceTemplate tpl = enterpriseDao.searchCustomerServiceTemplate(enterpriseId, tplCode);
    if (tpl == null) {
      doSendAlert(enterpriseId, "改签单(" + o.getOrderNo() + ")完成时, 未找到服务费模板(" + tplCode + ").", "Dai", 0);
      return null;
    }

    CustomerServiceTemplateDto tplDto = CustomerServiceTemplateDto.createBy(tpl);
    //改签服务费
    int changeFee = tplDto.getFlightChangeFee();
    List<CustomerServiceFlightRule> flightRules = enterpriseDao.searchCustomerServiceFlightRules(enterpriseId, tplDto.getTemplateCode());
    for (CustomerServiceFlightRule fltRule : flightRules) {
      for (FlightChangeOrderDetail flt : o.getFlights()) {
        if (fltRule.getCarrier().equalsIgnoreCase(flt.getFlight().getFlightNo().substring(0, 2))
                && fltRule.getSubclasses().contains(flt.getFlight().getSubclass())) {
          //使用具体航司的具体舱位的服务费规则
          changeFee = fltRule.getFlightChangeFee();
          break;
        }
      }
    }

    if (changeFee > 0 && Math.abs(changeFee - o.getServiceCharge()) > 0.001) {
      final String content = String.format("改签单(%s): 服务费模板(%d)设定服务费为(%d), 实际(%f).",
              o.getChangeOrderNo(), tpl.getStrength(), changeFee, o.getServiceCharge());
      doSendAlert(enterpriseId, content, null, EntDepartment.DEPT_ADMINISTRATOR);
      if (tpl.getStrength() == 10) {
        return JsonResult.createJsonResult(-2, content);
      }
    }

    return null;
  }

  @Override
  public JsonResult updateChangeOrderSupplier(int enterpriseId, String username, int orderId,
      int supplierId) {
    Supplier supplier = enterpriseDao.getSupplierById(supplierId);
    if (supplier == null || supplier.getEnterpriseId() != enterpriseId) {
      return JsonResult.createJsonResult(-1, "供应商不存在");
    }

    FlightChangeOrder order = dao.getFlightChangeOrderDetail(orderId);
    if (order == null || order.getEnterpriseId() != enterpriseId) {
      return JsonResult.createJsonResult(-2, "改签单不存在");
    }

    if (!username.equalsIgnoreCase(order.getTicketer())) {
      return JsonResult.createJsonResult(-3, "你不是改签单的处理人");
    }

    int retCode = dao.updateSupplier(enterpriseId, username, orderId, supplier);

    return JsonResult.createJsonResult(retCode);
  }

  @Override
  public JsonResult updateChangeOrderPayment(int enterpriseId, String username, int orderId,
      int paymentMethodId) {
    PaymentMethod o = enterpriseDao.getPaymentMethodById(paymentMethodId);
    if (o == null || o.getEnterpriseId() != enterpriseId) {
      return JsonResult.createJsonResult(-1, "支付方式不存在");
    }

    FlightChangeOrder order = dao.getFlightChangeOrderDetail(orderId);
    if (order == null || order.getEnterpriseId() != enterpriseId) {
      return JsonResult.createJsonResult(-2, "改签单不存在");
    }

    if (!username.equalsIgnoreCase(order.getTicketer())) {
      return JsonResult.createJsonResult(-3, "你不是改签单的处理人");
    }

    int retCode = dao.updatePaymentMethod(enterpriseId, username, orderId, o);

    return JsonResult.createJsonResult(retCode);
  }

  @Override
  public JsonResult updateChangeOrderRemark(int enterpriseId, String username, int orderId,
      String remark) {
    int retCode = dao.updateChangeOrderRemark(enterpriseId, username, orderId, remark);

    return JsonResult.createJsonResult(retCode);
  }

  /**
   * 修改改签单的票号
   * @param enterpriseId 企业id
   * @param username 用户名
   * @param orderId 订单id
   * @param ticketNo 新票号
   */
  @Override
  @Secured({RoleInfo.ROLE_ADMIN})
  public JsonResult updateChangeOrderTicketNo(int enterpriseId, String username, int orderId,
      final String ticketNo) {
    //校验票号
    if (!FlightTicketUtil.verifyTicketNo(ticketNo)) {
        return JsonResult.createJsonResult(-1, "票号(" + ticketNo + ")不符合规范");
    }

    final String balCode = ticketNo.substring(0, 3);
    final String tickNo =
        ticketNo.length() == 14 ? ticketNo.substring(4) : ticketNo.substring(3);

    try {
      int retCode = dao.updateChangeOrderTicketNo(enterpriseId, username, orderId, balCode, tickNo);

      if (retCode == 1) {
        doSendAlert(enterpriseId, "改签单(" + orderId + ")的票号修改为：" + ticketNo, null, EntDepartment.DEPT_ADMINISTRATOR);
      }

      return JsonResult.createJsonResult(retCode);
    } catch (RuntimeException ex) {
      logger.error(ex.getMessage());
      return JsonResult.createJsonResult(-100, ex.getMessage());
    }
  }

  @Override
  public JsonResult updateChangeOrderPrice(int enterpriseId, String username, int id,
      double airChangeCharge, double serviceCharge) {
    FlightChangeOrder order = dao.getFlightChangeOrderDetail(id);
    if (order == null || order.getEnterpriseId() != enterpriseId) {
      return JsonResult.createJsonResult(-2, "改签单不存在");
    }

    if (!username.equalsIgnoreCase(order.getTicketer())) {
      return JsonResult.createJsonResult(-3, "你不是改签单的处理人");
    }

    int retCode = dao
        .updateChangeOrderPrice(enterpriseId, username, id, airChangeCharge, serviceCharge);
    return JsonResult.createJsonResult(retCode);
  }

  /**
   * 修改改签单的航班信息
   */
  @Override
  public JsonResult updateChangeOrderFlightInfo(final int enterpriseId, final String username,
      final int id, FlightChangeOrderDetail detail) {
    FlightChangeOrder order = dao.getFlightChangeOrderDetail(id);
    if (order == null || order.getEnterpriseId() != enterpriseId) {
      return JsonResult.createJsonResult(-1, "改签单不存在");
    }

    if (order.getStatus() == ORDER_STATUS_FINISHED || order.getStatus() == ORDER_STATUS_CANCELED) {
      return JsonResult.createJsonResult(-2, "改签单已处理完成");
    }

    int retCode;
    String remark = "";

    try {
      retCode = dao.updateChangeOrderFlightInfo(enterpriseId, username, id, detail);
    } catch (RuntimeException ex) {
      retCode = -100;
      remark = ex.getMessage();
    }
    return JsonResult.createJsonResult(retCode, remark);
  }

  /**
   * 回滚改签单状态
   */
  @Override
  @Secured({RoleInfo.ROLE_ADMIN, RoleInfo.ROLE_SUPERVISOR})
  public JsonResult rollbackChangeOrderStatus(final int enterpriseId, final String username,
      final int orderId, final String remark) {
    // 检查是否有对应的账单，如果有，就不能回滚
    FlightChangeOrder changeOrder = dao.getFlightChangeOrderDetail(orderId);
    if (changeOrder == null || changeOrder.getEnterpriseId() != enterpriseId) {
      return JsonResult.createJsonResult(-1, "数据错误");
    }

    List<BillInfo> billInfos = billService
        .searchBillInfoByOrderNo(enterpriseId, changeOrder.getChangeOrderNo());
    if (!billInfos.isEmpty()) {
      doSendAlert(enterpriseId, "改签单(" + changeOrder.getChangeOrderNo() + ")回滚失败，存在对应的账单", null,
          EntDepartment.DEPT_ADMINISTRATOR);
      return JsonResult.createJsonResult(-2, "存在对应的账单，不能回滚");
    }

    int retCode = dao.rollbackChangeOrderStatus(enterpriseId, username, orderId, remark);
    if (retCode > 0) {
      doSendAlert(enterpriseId, "改签单(" + changeOrder.getChangeOrderNo() + ")已回滚: " + remark, null,
          EntDepartment.DEPT_ADMINISTRATOR);
    }
    return JsonResult.createJsonResult(retCode);
  }

  /**
   * 改签单的短信内容
   */
  @Override
  public JsonResult getFlightChangeOrderSmsContent(int enterpriseId, String username, int orderId,
      int smsFormat) {

    FlightChangeOrder changeOrder = dao.getFlightChangeOrderDetail(orderId);

    String smsContent = generateChangeOrderSmsContent(enterpriseId, changeOrder, smsFormat);
    if (smsContent != null) {
      return JsonResult.createJsonResult(1, smsContent);
    } else {
      return JsonResult.createJsonResult(-1, "无法生成短信内容");
    }
  }

  @Override
  public JsonResult sendFlightChangeOrderSms(int enterpriseId, String username, int orderId,
      String mobileNo, int smsFormat, String smsContent0) {
    if (mobileNo != null && !CheckUtil.isMobileNo(mobileNo)) {
      return JsonResult.createJsonResult(-3, "无符合要求的手机号");
    }

    FlightChangeOrder changeOrder = dao.getFlightChangeOrderDetail(orderId);

    if (mobileNo == null) {
      mobileNo = changeOrder.getMobile();
      if (!CheckUtil.isMobileNo(mobileNo)) {
        return JsonResult.createJsonResult(-3, "改签单无符合要求的手机号");
      }
    }


    String smsContent =
        smsContent0 == null || smsContent0.trim().length() == 0 ? generateChangeOrderSmsContent(
            enterpriseId, changeOrder, smsFormat) : smsContent0;

    SmsDetail smsDetail = SmsDetail.createSmsDetail(enterpriseId, username, mobileNo, smsContent, changeOrder.getChangeOrderNo());

    return sendSms(smsDetail);
  }

  @Override
  public void refreshChangeOrderDetrDetail(final int enterpriseId, final String username) {
    List<FlightChangeOrder> changeOrders = dao.searchChangeOrdersNeedRefreshDetr(enterpriseId, 10);
    logger.info("refreshChangeOrderDetrDetail refundOrder's is {}.", changeOrders.size());

    for (FlightChangeOrder orderInfo : changeOrders) {
      if (orderInfo.getDetrRefreshStatus() != null && orderInfo.getDetrRefreshStatus() != 0) {
        continue;
      }

      if (orderInfo.getStatus() == ORDER_STATUS_FINISHED) {
        etermService.refreshChangeOrderDetrDetail(enterpriseId, username, orderInfo);
      }
    }

    processDetrInfo2ChangeOrder(enterpriseId, username);
  }

  /**
   * 将DETR信息的状态反馈到改签单中
   */
  private void processDetrInfo2ChangeOrder(final int enterpriseId, final String username) {
    //将DETR结果反馈到改签订单
    List<FlightChangeOrder> changeOrders = dao.searchChangeOrdersDetrFinished(enterpriseId, 100);

    for (FlightChangeOrder orderInfo : changeOrders) {
      doProcessDetrInfo2ChangeOrder(enterpriseId, username, orderInfo);
    }
  }

  private void doProcessDetrInfo2ChangeOrder(final int enterpriseId, final String username, FlightChangeOrder orderInfo) {
    if (orderInfo.getDetrRefreshStatus() == null || orderInfo.getDetrRefreshStatus() != 1) {
      return;
    }

    final Date saleDate = orderInfo.getCreateTime();
    final String ticketNo = orderInfo.getNewTicketNo().length() >= 13 ?
            orderInfo.getNewTicketNo() :
            orderInfo.getBalanceCode() + "-" + orderInfo.getTicketNo();

    //从DETR中获取对应的航段信息
    DetrInfo detrInfo = detrDao.getByTicketNo(enterpriseId, ticketNo.replace("-", ""));
    if (detrInfo == null) {
      logger.warn("{}, {}, {}", enterpriseId,  saleDate, ticketNo);
      return;
    }

    int finalStatus = 1;
    for (DetrInfoFlight detrInfoFlight : detrInfo.getFlights()) {
      final String tktStatus = detrInfoFlight.getTicketStatus().trim();
      if (convertTktStatus2FinalStatus(tktStatus) == 0) {
        finalStatus = 0;
        break;
      }
    }

    if (finalStatus == 1) {
      //票号已为最终状态
      dao.updateChangeOrderDetrStatus(enterpriseId, username, orderInfo.getId(), 8);
    }
  }

  /**
   * 判断机票航段状态是否为终态
   * @return -1 - 未知
   *          0 - 不是终态
   *          1 - 是终态
   */
  private int convertTktStatus2FinalStatus(final String tktStatus) {
    if (DETR_OPEN_FOR_USE.equalsIgnoreCase(tktStatus)) {
      return 0;
    } else if (DETR_USED_FLOWN.equalsIgnoreCase(tktStatus)
            || DETR_EXCHANGED.equalsIgnoreCase(tktStatus)
            || DETR_REFUNDED.equalsIgnoreCase(tktStatus)) {
      return 1;
    } else {
      return 0;
    }
  }

  @Override
  public void recheckChangeOrderDetrInfo(final int enterpriseId, final String username) {
    List<FlightChangeOrder> changeOrders = dao.searchChangeOrdersNeedRecheckDetr(enterpriseId, 100);

    for(FlightChangeOrder o: changeOrders) {
      //检查是否要重新更新DETR信息
      if (o.getDetrRefreshTime() == null) {
        continue;
      }

      //检查票号是否都到了终态
      if (o.getDetrRefreshStatus() != null && o.getDetrRefreshStatus() == 8) {
        continue;
      }

      final long pastHours = DateUtil.getPastHours(o.getDetrRefreshTime());
      if (pastHours < 24) {
        continue;
      }

      //重置DETR状态，更新DETR信息
      dao.updateChangeOrderDetrStatus(enterpriseId, username, o.getId(), 0);
    }

  }

  @Override
  public void refreshChangeOrderPnrDetail(int enterpriseId, String username) {
    List<FlightChangeOrder> changeOrders = changeOrderDao.searchChangeOrdersNeedRefreshPnr(enterpriseId, 100);
    for(FlightChangeOrder changeOrder: changeOrders) {
      if (changeOrder.getPnrRefreshStatus() != null) {
        continue;
      }

      if (changeOrder.getOldPnrNo() == null || changeOrder.getOldPnrNo().trim().length() < 6) {
        continue;
      }

      if (changeOrder.getStatus() != FlightChangeOrder.ORDER_STATUS_FINISHED) {
        continue;
      }

      etermService.refreshChangeOrderPnrDetail(enterpriseId, username, changeOrder);
    }
  }

  @Override
  public JsonResult saveChangeOrderAttachment(int enterpriseId, String username, int orderId, List<OrderAttachment> attachments) {
    for(OrderAttachment oa: attachments) {
      oa.setOrderType(ORDER_TYPE_FLIGHT_CHANGE);
      oa.setEnterpriseId(enterpriseId);
      oa.setOrderId(orderId);
    }

    int retCode = dao.saveChangeOrderAttachment(enterpriseId, username, orderId, attachments);

    return JsonResult.createJsonResult(retCode);
  }

  @Override
  public JsonResult sendWeixinTplMsg(int enterpriseId, int id) {
    FlightChangeOrder order = dao.getFlightChangeOrderDetail(id);

    //TODO 发送微信模板消息通知微信用户
    try {
      doSendWeixinTemplateMessage("oEK0T0sye8VHx3ywNellAehPY-8Y", enterpriseId, order);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    return null;
  }

  @Override
  public JsonResult createNdcOrderChange(final int enterpriseId, final String username, final int orderId) {
    var changeOrder = dao.getFlightChangeOrderDetail(orderId);
    if (StringUtils.isNotBlank(changeOrder.getExternalOrderNo())) {
      return JsonResult.createJsonResult(-1, "已存在外部订单号");
    }

    var rq = new cn.buk.api.airskyhk.dto.OrderChangeRequest();

    rq.getMemberInfo().setAccountNumber(doGetEntCfg(enterpriseId, TMS_DEFAULT_LINK_MOBILE));

    cn.buk.api.airskyhk.dto.ContactInfo contactInfo = new cn.buk.api.airskyhk.dto.ContactInfo();
    contactInfo.setContactName(doGetEntCfg(enterpriseId, TMS_DEFAULT_LINKMAN));
    contactInfo.setMobile(doGetEntCfg(enterpriseId, TMS_DEFAULT_LINK_MOBILE));
    contactInfo.setPhoneNumber(doGetEntCfg(enterpriseId, TMS_DEFAULT_LINK_PHONE));
    contactInfo.setEmail(doGetEntCfg(enterpriseId, TMS_DEFAULT_LINK_EMAIL));

    contactInfo.setSurname(changeOrder.getPsgName());
    rq.getRequest().getContacts().add(contactInfo);

    for(var flt: changeOrder.getFlights()) {
      var f = flt.getFlight();
      FlightInfo flightInfo = createFlightInfo(f.getDport(), f.getAport(), f.getDdate(), f.getFlightNo(), f.getSubClass(),
              f.getDtime(), f.getAtime(), f.getDterm(), f.getAterm());
      if (flt.getFlightType() == 1) {
        rq.getRequest().getFlights().add(flightInfo);
      } else {
        rq.getRequest().getOriginalFlights().add(flightInfo);
      }
    }

    var flightOrder = flightOrderDao.getOrderDetailByOrderNo(enterpriseId, changeOrder.getOrderNo());

    rq.getRequest().setOrderNo(flightOrder.getExternalOrderNo());
    rq.getRequest().setPnr(flightOrder.getBigPnrNo());


    Pax pax = new Pax();
    pax.setPassengerType("ADT");
    pax.setSurname(changeOrder.getPsgName());
    pax.setTicketNumber(changeOrder.getBalanceCode() + changeOrder.getTicketNo());
    rq.getRequest().getPassengers().add(pax);



    //记录查询日志
    final int queryId = userDao.createEtermCmdLog(enterpriseId, username, "NDC_创建改签单", flightOrder.getOrderNo());
    rq.getPayloadAttributes().setTransactionId(queryId + "");

    var ndcService = createNdcService(enterpriseId);
    try {
      var rs = ndcService.createChangeOrder(rq);
      userDao.updateEtermCmdLog(queryId, rs.getRequestStr(), rs.getResponseStr());

      if ("SUCCESS".equalsIgnoreCase(rs.getStatus().getStatus())) {
        String externalOrderNo = rs.getResponse().getOrder().getOrderNo();
        int retCode = changeOrderDao.updateExternalOrderNo(enterpriseId, username, orderId,
                externalOrderNo, "保存外部改签单号(" + externalOrderNo + ")");
        return JsonResult.createJsonResult(retCode, "外部改签单号：" + externalOrderNo + ".");
      } else {
        final String msg = rs.getStatus().getErrorCode() + ": " + rs.getStatus().getErrorMessage();
        changeOrderDao.appendFlightChangeOrderLog(enterpriseId, orderId, username, msg);

        return JsonResult.createJsonResult(-1, rs.getStatus().getErrorMessage());
      }
    } catch (Exception ex) {
      return JsonResult.createJsonResult(-100, "提交改签单时，提示 " + ex.getMessage());
    }
  }

  @Override
  public JsonResult syncNdcOrderChangeInfo(int enterpriseId, String username, int orderId) {
    var changeOrder = dao.getFlightChangeOrderDetail(orderId);
    if (changeOrder == null || changeOrder.getEnterpriseId() != enterpriseId) {
      return JsonResult.createJsonResult(-1, "Order is not existed.");
    }

    if (StringUtils.isBlank(changeOrder.getExternalOrderNo())) {
      return JsonResult.createJsonResult(-3, "无外部订单号");
    }

    var rq = new OrderRetrieveRequest();

    rq.getMemberInfo().setAccountNumber(doGetEntCfg(enterpriseId, TMS_DEFAULT_LINK_MOBILE));

    final String externalOrderNo = changeOrder.getExternalOrderNo();
    rq.getRequest().setOrderNo(externalOrderNo);
    rq.getRequest().setPnr(changeOrder.getNewBigPnr());


    //记录查询日志
    final int queryId = userDao.createEtermCmdLog(enterpriseId, username, "CZ_NDC_改签单查询", changeOrder.getChangeOrderNo());
    rq.getPayloadAttributes().setTransactionId(queryId + "");

    var ndcService = createNdcService(enterpriseId);
    var rs = ndcService.searchOrder(rq);
    userDao.updateEtermCmdLog(queryId, rs.getRequestStr(), rs.getResponseStr());


    return processCzNdcOrderSyncResult(enterpriseId, username, changeOrder, rs);
  }

  @Override
  public JsonResult payForFlightChangeOrder(int enterpriseId, String username, int orderId) {
    var changeOrder = changeOrderDao.getFlightChangeOrderDetail(orderId);
    if (changeOrder == null || changeOrder.getEnterpriseId() != enterpriseId) {
      return JsonResult.createJsonResult(-1, "Order is not existed.");
    }

    if (changeOrder.getSupplier() == null || changeOrder.getSupplier().getIsBsp() != FLIGHT_AUTO_TICKETING_NDC_CZ) {
      return JsonResult.createJsonResult(-2, "not CZ NDC supplier.");
    }

    if (StringUtils.isBlank(changeOrder.getExternalOrderNo())) {
      return JsonResult.createJsonResult(-3, "无外部订单号");
    }
    var rq = new AirDocIssueRequest();

    rq.getMemberInfo().setAccountNumber(doGetEntCfg(changeOrder.getEnterpriseId(), TMS_DEFAULT_LINK_MOBILE));

    final String externalOrderNo = changeOrder.getExternalOrderNo();
    rq.getRequest().getOrder().setOrderNo(externalOrderNo);
    rq.getRequest().getOrder().setTotalAmount(changeOrder.getAirChangeCharge());

    rq.getRequest().getPayment().setPayType("BWP");
    rq.getRequest().getPayment().setTransType("01");
    rq.getRequest().getPayment().setAccountType("02");

    //记录查询日志
    final int queryId = userDao.createEtermCmdLog(enterpriseId, username, "CZ_NDC_改签单支付", changeOrder.getOrderNo());
    rq.getPayloadAttributes().setTransactionId(queryId + "");

    var ndcService = createNdcService(enterpriseId);
    var rs = ndcService.payForOrder(rq);
    userDao.updateEtermCmdLog(queryId, rs.getRequestStr(), rs.getResponseStr());


    if (SUCCESS.equalsIgnoreCase(rs.getStatus().getStatus())) {
      final String orderStatus = rs.getResponse().getOrder().getStatus();
      final String orderStatusDesc = rs.getResponse().getOrder().getStatusDesc();
      changeOrderDao.appendFlightChangeOrderLog(enterpriseId, orderId, username, externalOrderNo + ": " + orderStatus + ", " + orderStatusDesc);
      return JsonResult.createJsonResult(1, "支付成功");
    } else {
      //03:余额账户资金不足
      //一小时暂停
      final String key = String.format(CZ_NDC_AMOUNT_BALANCE, enterpriseId);
      redisDao.setAndExpire(key, (changeOrder.getAirChangeCharge() + "").getBytes(UTF_8), 60L * 60);

      changeOrderDao.appendFlightChangeOrderLog(enterpriseId, orderId, username, "CZ_NDC支付: " + rs.getStatus().getErrorMessage());

      String content = "改签单(" + changeOrder.getChangeOrderNo() + ")使用CZ_NDC支付" + changeOrder.getAirChangeCharge() + "时，提示 " + rs.getStatus().getErrorMessage();
      doSendAlert(enterpriseId,  content, null, EntDepartment.DEPT_ADMINISTRATOR);

      return JsonResult.createJsonResult(-10, rs.getStatus().getErrorMessage());
    }
  }

  private JsonResult processCzNdcOrderSyncResult(int enterpriseId, String username, FlightChangeOrder changeOrder, OrderViewResponse rs) {
    var jr = JsonResult.createJsonResult(1);
    final String externalOrderNo = changeOrder.getExternalOrderNo();
    final int orderId = changeOrder.getId();
    if (!SUCCESS.equalsIgnoreCase(rs.getStatus().getStatus())) {
      return JsonResult.createJsonResult(-4, rs.getStatus().getErrorMessage());
    }

    if (!externalOrderNo.equalsIgnoreCase(rs.getResponse().getOrder().getOrderNo())) {
      return JsonResult.createJsonResult(-3, "订单号不符");
    }

    rs.getResponse().getOrder().setOrderType(2); //设置为改签单，返回改签单的状态说明
    final String orderStatus = rs.getResponse().getOrder().getStatus();
    final String orderStatusDesc = rs.getResponse().getOrder().getStatusDesc();

    changeOrderDao.appendFlightChangeOrderLog(enterpriseId, orderId, username, externalOrderNo + ": " + orderStatus + ", " + orderStatusDesc);


    return jr;
  }

  private static FlightInfo createFlightInfo(String dport, String aport, String ddate, String flightNo, String subClass,
                                             String dtime, String atime, String dterm, String aterm) {
    var t = new FlightInfo();

    t.getDeparture().setAirportCode(dport);
    t.getDeparture().setScheduledDate(ddate);
    t.getDeparture().setScheduledTime(dtime);
    t.getDeparture().setTerminalName(dterm);

    t.getArrival().setAirportCode(aport);
    t.getArrival().setScheduledDate(ddate);
    t.getArrival().setScheduledTime(atime);
    t.getArrival().setTerminalName(aterm);

    t.setCabin(subClass);

    t.setMarketingFlightNo(flightNo);

    return t;
  }

  private String generateChangeOrderSmsContent(int enterpriseId, FlightChangeOrder changeOrder,
      int smsFormat) {

    processOrderAirportName(changeOrder);

    return generateSmsContentByTemplate(enterpriseId, smsFormat, changeOrder);
  }

  private String generateSmsContentByTemplate(int enterpriseId, int smsFormat,
      FlightChangeOrder order) {
    final String companySign = doGetEntCfg(enterpriseId, EnterpriseConfig.API_SMS_COMPANY_SIGN);
    final String psgName = order.getPsgName() + "(" + order.getIdNo() + ")";
    final String smsRouteInfo = SmsUtil.convertChangeOrder(order);
    final String ticketNo = order.getNewTicketNo().length() < 13 ?
                order.getBalanceCode() + order.getTicketNo() : order.getNewTicketNo();

    String smsContent = null;
    if (smsFormat == 0) {
      smsContent = String
          .format(CHANGE_SMS_TEMPLATE_1, companySign, psgName, smsRouteInfo, ticketNo);
    }

    return smsContent;
  }


}
